<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: Serialization</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
  $(document).ready(function() { init_search(); });
/* @license-end */
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr id="projectrow">
  <td id="projectlogo"><img alt="Logo" src="aslogo_small.png"/></td>
  <td id="projectalign">
   <div id="projectname">AngelScript
   </div>
  </td>
    <td>        <div id="MSearchBox" class="MSearchBoxInactive">
        <span class="left">
          <span id="MSearchSelect"                onmouseover="return searchBox.OnSearchSelectShow()"                onmouseout="return searchBox.OnSearchSelectHide()">&#160;</span>
          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)" 
               onblur="searchBox.OnSearchFieldFocus(false)" 
               onkeyup="searchBox.OnSearchFieldChange(event)"/>
          </span><span class="right">
            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
          </span>
        </div>
</td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.6 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(document).ready(function(){initNavTree('doc_serialization.html',''); initResizable(); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>

<div><div class="header">
  <div class="headertitle"><div class="title">Serialization </div></div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p>To serialize scripts the application needs to be able to iterate through all variables, and objects that have any relation to the script and store their content in a way that would allow it to be restored at a later time. For simple values this is trivial, but for objects and handles it becomes more complex as it is necessary to keep track of references between objects and internal structure of both classes defined by scripts and application registered types.</p>
<p>Iterating through the variables and members of objects is already described in the article about <a class="el" href="doc_adv_reflection.html">reflection</a>, so this article will focus on the storing and restoring of values.</p>
<p>Look at the source code for the <a class="el" href="doc_addon_serializer.html">Serializer</a> add-on for a sample implementation of serialization.</p>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="doc_adv_dynamic_build.html#doc_adv_dynamic_build_hot">Hot reloading scripts</a></dd></dl>
<h1><a class="anchor" id="doc_serialization_modules"></a>
Serialization of modules</h1>
<p>To serialize the script modules you'll need to enumerate all the global variables and <a class="el" href="doc_serialization.html#doc_serialization_vars">serialize each of them</a>.</p>
<p>When deserializing the module, first compile it normally either from <a class="el" href="doc_compile_script.html">source script</a> or by <a class="el" href="doc_adv_precompile.html">loading a pre-compiled byte code</a>, except you first need to turn off initialization of global variables by <a class="el" href="classas_i_script_engine.html#a1bce4e5f573a2ca0ff55163e28f761dd">turning off the engine property asEP_INIT_GLOBAL_VARS_AFTER_BUILD</a>.</p>
<h1><a class="anchor" id="doc_serialization_vars"></a>
Serialization of global variables</h1>
<p>To serialize a global variable you'll need the name and namespace to use as the key for the variable, and then the type id and address of the variable. You get these with the methods <a class="el" href="classas_i_script_module.html#a939e6caf004c6fdae78fe89bb244d962">asIScriptModule::GetGlobalVar</a> and <a class="el" href="classas_i_script_module.html#aa305c506281141e0da4cb77b944d9494">asIScriptModule::GetAddressOfGlobalVar</a>. If the type id is for a primitive type, then the value can be stored as is. If it is a handle or reference you'll need to serialize the reference itself and the object it refers to. If the type id is an object type then <a class="el" href="doc_serialization.html#doc_serialization_objects">serialize the object</a> and its content.</p>
<p>To deserialize the global variable, you'll use the name and namespace to look it up, and then use GetAddressOfGlobalVar to get the address of the memory that needs to be restored with the serialized content.</p>
<h1><a class="anchor" id="doc_serialization_objects"></a>
Serialization of objects</h1>
<p>To serialize script objects you'll use the <a class="el" href="classas_i_script_object.html">asIScriptObject</a> interface to iterate over the members to store the content. Remember that objects can hold references to other objects and even to itself so it is important to keep track of object instances already serialized and just store a reference if the same object comes up again.</p>
<p>When deserializing the script objects you should first allocate the memory using <a class="el" href="classas_i_script_engine.html#ae1ce277867b06582353348f33a6837aa">asIScriptEngine::CreateUninitializedScriptObject</a> so that the constructor is not executed, and then iterate over the members to restore their content.</p>
<p>For application registered types you obviously need to provide your own implementation as the script engine doesn't know the full content of the types and thus cannot provide an interface for serialization.</p>
<h1><a class="anchor" id="doc_serialization_contexts"></a>
Serialization of contexts</h1>
<p>Serialization of a script context involves storing the full call stack with all the function calls, local variables, registers, etc. To do this you'll use the <a class="el" href="classas_i_script_context.html">asIScriptContext</a> interface.</p>
<ul>
<li>Use <a class="el" href="classas_i_script_context.html#aab359abc4563a8439338bfd655824bd7">GetCallstackSize</a> to get the size of the call stack</li>
<li>For each call stack entry do:<ul>
<li>Use <a class="el" href="classas_i_script_context.html#a84b6df2e303216afdc9859157e92fd12">GetCallStateRegisters</a> to store the registers, i.e. program pointer, stack pointer, etc.</li>
<li>Use <a class="el" href="classas_i_script_context.html#a3d735c6c7c5a166302cc4ba8ea38e3e8">GetVarCount</a>, <a class="el" href="classas_i_script_context.html#a624d083a5890e2de678eae3277b450d7">GetVar</a>, and <a class="el" href="classas_i_script_context.html#a1f9f028a1fb9e9834487eece12d06f8a">GetAddressOfVar</a> to store all local variables, including unnamed temporary variables</li>
<li>Use <a class="el" href="classas_i_script_context.html#a7f5635bba06dc5ee2fd4b0dd05a03dcb">GetArgsOnStackCount</a> and <a class="el" href="classas_i_script_context.html#a058814abeabfd6819120499b8517f9c9">GetArgOnStack</a> to store values pushed on the stack for a subsequent function call</li>
</ul>
</li>
<li>Use <a class="el" href="classas_i_script_context.html#a7301c742aaca2d95278fd0a2c3725637">GetStateRegisters</a> to store additional context registers <br  />
</li>
</ul>
<p>To deserialize a context follow these steps:</p>
<ul>
<li>Call <a class="el" href="classas_i_script_context.html#a6a1460706a70c27ec4542dbcb7379391">StartDeserialization</a> to tell the context that a deserialization will be done</li>
<li>For each call stack entry previously stored do:<ul>
<li>Call <a class="el" href="classas_i_script_context.html#a4bb456f49a8caaa36db7c971c58b56c7">PushFunction</a> to reserve space for a call stack entry</li>
<li>Call <a class="el" href="classas_i_script_context.html#a99dcf986ed3c381e727276a7f19d200c">SetCallStateRegisters</a> to restore the registers</li>
<li>Use <a class="el" href="classas_i_script_context.html#a624d083a5890e2de678eae3277b450d7">GetVar</a> and <a class="el" href="classas_i_script_context.html#a1f9f028a1fb9e9834487eece12d06f8a">GetAddressOfVar</a> to restore all local variables</li>
<li>Use <a class="el" href="classas_i_script_context.html#a058814abeabfd6819120499b8517f9c9">GetArgOnStack</a> to restore values pushed on the stack</li>
</ul>
</li>
<li>Call <a class="el" href="classas_i_script_context.html#a9585faeead1cbe82065132b85ffb2db8">SetStateRegisters</a> to restore additional context registers</li>
<li>Call <a class="el" href="classas_i_script_context.html#ae804cb97a93a4524c0cd374d82ebaa9c">FinishDeserialization</a> to conclude the serialization and allow the execution to resume</li>
</ul>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000001">Todo:</a></b></dt><dd>Add information on known restrictions, e.g. serialized contexts can only be restored on same cpu architecture, etc</dd></dl>
</div></div><!-- contents -->
</div><!-- PageDoc -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
  <ul>
    <li class="footer">Generated on Sun May 21 2023 10:12:40 for AngelScript by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.6 </li>
  </ul>
</div>
</body>
</html>
